/*
 * Lucas McDaniel
 * GSoC '11
 * HoneyViz
 * 
 * 
 */

import java.awt.Color;
import java.awt.Paint;
import java.util.ArrayList;

public class EventColorManager {
    
    public static ArrayList list = new ArrayList();
    public static ArrayList paints = new ArrayList();
    public static ArrayList paintsSorted = new ArrayList();
    public static ArrayList sortedEvents = new ArrayList();
    
    public static ArrayList storedList = new ArrayList();
    public static ArrayList storedPaints = new ArrayList();
    public static ArrayList storedPaintsSorted = new ArrayList();
    public static ArrayList storedSortedEvents = new ArrayList();
    
    private static int currentMode = 0;
    private static int currentPViz = 0;
    private static int currentSViz = 0;
    private static int currentPStat = 0;
    private static int currentPSearch = 0;
    
    public EventColorManager()
    {}
    
    public static void changeMode()
    {
        if (AppletState.getMode() == currentMode && currentMode != -1)
            return;
        if (currentMode == -1 && (currentPViz == AppletState.getPrimaryViz() && 
                currentSViz == AppletState.getSecondaryViz() &&
                currentPStat == AppletState.getPrimaryStat() &&
                currentPSearch == AppletState.getPrimarySearch()))
            return;
        
        storedList.add(currentPSearch, list);
        storedPaints.add(currentPSearch, paints);
        storedPaintsSorted.add(currentPSearch, paintsSorted);
        storedSortedEvents.add(currentPSearch, sortedEvents);
        
        currentMode = AppletState.getMode();
        currentPViz = AppletState.getPrimaryViz();
        currentSViz = AppletState.getSecondaryViz();
        currentPStat = AppletState.getPrimaryStat();
        currentPSearch = AppletState.getPrimarySearch();
        
        if (storedList.size()>currentPSearch)
        {
            list = (ArrayList)storedList.get(currentPSearch);
            paints = (ArrayList)storedPaints.get(currentPSearch);
            paintsSorted = (ArrayList)storedPaintsSorted.get(currentPSearch);
            sortedEvents = (ArrayList)storedSortedEvents.get(currentPSearch);
        }
        else
        {
            list = new ArrayList();
            paints = new ArrayList();
            paintsSorted = new ArrayList();
            sortedEvents = new ArrayList();
        }
        AppletState.resetSelected();
    }
    
    public static void add(EventColor e)
    {
        for (int inc=0; inc<list.size(); inc++)
            if (((EventColor)list.get(inc)).name.compareTo(e.name)>0)
            {
                list.add(inc, e);
                return;
            }
        list.add(e);
    }
    
    public static ArrayList getNameList()
    {
        ArrayList rtnVal = new ArrayList();
        for (int inc=0; inc<list.size(); inc++)
            rtnVal.add(((EventColor)list.get(inc)).name);
        return rtnVal;
    }
    
    public static int size()
    {
        return list.size();
    }
    
    public static int getIndexOf(String name)
    {
        for (int inc=0; inc<list.size(); inc++)
            if (((EventColor)list.get(inc)).name.compareTo(name)==0)
                return inc;
        return -1;
    }
    
    public static EventColor byName(String name)
    {
        return (EventColor)list.get(getIndexOf(name));
    }
    
    public static EventColor getEvent(int index)
    {
        return (EventColor)list.get(index);
    }
    
    public static EventColor getEvent(String index)
    {
        int arrIndex = getIndexOf(index);
        if (arrIndex==-1)
            return new EventColor("Group", -1, Color.RED, 0, 0);
        return (EventColor)list.get(arrIndex);
    }
    
    public static void reset()
    {
        list = new ArrayList();
    }
    
    public static void makeColors(ArrayList results)
    {
        ArrayList sorted = new ArrayList();
        sortedEvents = new ArrayList();
        for (int inc=0; inc<results.size(); inc++)
        {
            DataElement DE = (DataElement)results.get(inc);
            boolean added = false;
            for (int inc2=0; inc2<sorted.size(); inc2++)
                if (((DataElement)sorted.get(inc2)).count < DE.count)
                {
                    sorted.add(inc2, DE);
                    added = true;
                    break;
                }
            if (!added)
                sorted.add(DE);
        }
        if (paints.size()==0)
        {
            paints.add(new Color(255, 0, 0));
            paints.add(new Color(0, 255, 0));
            paints.add(new Color(0, 0, 255));
            paints.add(new Color(255, 255, 0));
            paints.add(new Color(0, 255, 255));
            paints.add(new Color(255, 0, 255));
            paintsSorted.add(new Color(255, 0, 0));
            paintsSorted.add(new Color(255, 255, 0));
            paintsSorted.add(new Color(0, 255, 0));
            paintsSorted.add(new Color(0, 255, 255));
            paintsSorted.add(new Color(0, 0, 255));
            paintsSorted.add(new Color(255, 0, 255));
        }
        while(list.size()>=paints.size())
        {
            ArrayList newColors = new ArrayList();
            for (int inc=0; inc<paintsSorted.size()-1; inc++)
                newColors.add(combine((Color)paintsSorted.get(inc), (Color)paintsSorted.get(inc+1)));
            newColors.add(combine((Color)paintsSorted.get(0), (Color)paintsSorted.get(paintsSorted.size()-1)));
            for (int inc=0; inc<newColors.size(); inc++)
                paintsSorted.add((2*inc+1),newColors.get(inc));
            paints.addAll(newColors);
        }
        for (int inc=0; inc<sorted.size(); inc++)
        {
            if (AppletState.getPrimarySearch()==0)
                ((EventColor)list.get(getIndexOf(((DataElement)sorted.get(inc)).name))).set(inc, getNextColor(inc));
            else
                ((EventColor)list.get(getIndexOf(LocationManager.getLocationName((DataElement)sorted.get(inc))))).set(inc, getNextColor(inc));
        }
        for (int inc=0; inc<sorted.size(); inc++)
        {
            if (AppletState.getPrimarySearch()==0)
                sortedEvents.add(getEvent(((DataElement)sorted.get(inc)).name).makeNew());
            else
                sortedEvents.add(getEvent(LocationManager.getLocationName((DataElement)sorted.get(inc))));
            EventColor ec = getEvent(((DataElement)sorted.get(inc)).name);
        }
    }
    
    public static EventColor getTempEvent(String index)
    {
        int arrIndex = getTempIndexOf(index);
        if (arrIndex==-1)
            return new EventColor("Group", -1, Color.RED);
        return (EventColor)sortedEvents.get(arrIndex);
    }
    
    public static int getTempIndexOf(String name)
    {
        for (int inc=0; inc<sortedEvents.size(); inc++)
            if (((EventColor)sortedEvents.get(inc)).name.compareTo(name)==0)
                return inc;
        return -1;
    }
    
    public static Color combine(Color c1, Color c2)
    {
        int r1 = c1.getRed();
        int g1 = c1.getGreen();
        int b1 = c1.getBlue();
        int r2 = c2.getRed();
        int g2 = c2.getGreen();
        int b2 = c2.getBlue();
        int r = (r1 + r2)/2;
        int g = (g1 + g2)/2;
        int b = (b1 + b2)/2;
        return new Color(r, g, b);
    }
    
    public static Color getNextColor(int index)
    {
        return (Color)paints.get(index);
    }
    
    public static Paint[] getColors()
    {
        Paint[] rtnVal = new Paint[list.size()];
        for (int inc=0; inc<list.size(); inc++)
            rtnVal[inc] = ((EventColor)list.get(inc)).paint;
        return rtnVal;
    }
    
    public static void print()
    {
        for (int inc=0; inc<list.size(); inc++)
            System.out.println(((EventColor)list.get(inc)).name + "\t" + ((EventColor)list.get(inc)).paint + "\t" + ((EventColor)list.get(inc)).key);
    }
    
    public static Color[] getPaints()
    {
        Color[] rtnVal = new Color[size()];
        for (int inc=0; inc<size(); inc++)
            rtnVal[inc] = (Color)paints.get(inc);
        return rtnVal;
    }
    
    public static void updateColors()
    {
        for (int inc=0; inc<sortedEvents.size(); inc++)
        {
            EventColor ec = (EventColor)sortedEvents.get(inc);
            getEvent(ec.name).paint = ec.paint;
        }
        AppletState.setUpdate();
    }
}
